global cropflip_asm

%define tamx [RBP + 16]
%define tamy [RBP + 24]
%define offsetx [RBP + 32]
%define offsety [RBP + 40]

section .text
;void tiles_asm(unsigned char *src,
;              unsigned char *dst,
;		int cols, rows
;              int src_row_size,
;              int dst_row_size,
;		int tamx, int tamy,
;		int offsetx, int offsety);
; src: RDI
; dst: RSI
; cols: RDX
; rows: RCX
; src_row_size : R8
; dst_row_size: R9
; tamx: [RBP + 16]
; tamy: [RBP + 24]
; offsetx: [RBP + 32]
; offsety: [RBP + 40]


cropflip_asm:
    PUSH RBP
    MOV RBP, RSP
    PUSH R12
    PUSH R13 
    PUSH R14
    PUSH R15
    PUSH RBX
    
    XOR R12, R12
    XOR R14, R14
    XOR R15, R15

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; paso a registros los parametros de la funcion que quedaron
    ; en lapila
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    MOV R12d, tamy
    MOV R13d, tamx
    MOV R14d, offsety
    MOV R15d, offsetx
    SHL RDX, 32
    SHR RDX, 32

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; obtengo el offset que tengo que sumar 
    ; para desplazamiento vertical (offsety)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    MOV RBX, R13					; guardo RDX

    XOR RAX, RAX
    MOV EAX, R8d 
    MUL R14d						; multiplico el src_row_size por el offsety
    
 
 
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; obtengo el desplazamiento en el offset y (sumo 4 porque 
    ; cada pixel tiene 4 bytes)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;		
    ADD RAX, R15
    ADD RAX, R15
    ADD RAX, R15 					
    ADD RAX, R15

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; obtengo el offset total en x e y para la imagen fuente
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;		    
    MOV R10, RAX

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; obtengo un puntero al comienzo de la última fila
    ; de la imagen destino
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;		    
    XOR RAX, RAX
    MOV EAX, R9d
    DEC R12d
    MUL R12d							; multiplico el dst_row_size por el tamy
    INC R12d
    ADD RSI, RAX

    MOV RDX, RBX
    
    XOR RBX, RBX
    XOR RAX, RAX
    MOV RAX, RDX
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; obtengo en RDX la cantidad de bytes con componentes
    ; de pixeles que hay en una fila
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;		    
    ADD RDX, RDX
    ADD RDX, RDX					; me quedo con columnas por 4, ya que cada píxel tiene 4 bytes.
.ciclo_filas:
    CMP R12d, 0
    JE .fin
    MOV RAX, RDX
    XOR RBX, RBX
    MOV RBX, R10
.ciclo_columnas:
    CMP RAX, 0
    JE .fin_ciclo_columnas
    CMP RAX, 16
    JL .ajustar_por_borde
    MOVUPS XMM0, [RDI + RBX]
    SUB RAX, 16
    ADD RBX, 16
    MOVUPS [RSI], XMM0
    ADD RSI, 16
    JMP .ciclo_columnas
.ajustar_por_borde:
    SUB RAX, 16
    ADD RBX, RAX
    ADD RSI, RAX
    MOV RAX, 16
    JMP .ciclo_columnas    
.fin_ciclo_columnas:
    ADD RDI, R8
    SUB RSI, RDX
    SUB RSI, R9
    DEC R12d
    JMP .ciclo_filas 

.fin:

    POP RBX
    POP R15
    POP R14 
    POP R13
    POP R12
    POP RBP
    RET
